﻿using System;
using System.Collections.Generic;
using System.Text;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Reflection;
using System.IO;
using Microsoft.VisualStudio.TextTemplating;

namespace CoNatural.Data.VisualStudio.AddIn.Tools {
	[Serializable]
	public class TextTemplatingEngineHostBase : MarshalByRefObject, ITextTemplatingEngineHost, IDisposable {
		public string Namespace { get; set; }
		public string Name { get; set; }

		public CompilerErrorCollection Errors { get; private set; }
		public AppDomain AppDomain { get; private set; }

		#region ITextTemplatingEngineHost Members

		public object GetHostOption(string optionName) {
			return optionName != null && optionName == "CacheAssemblies";
		}

		public bool LoadIncludeText(string requestFileName, out string content, out string location) {
			content = string.Empty;
			location = string.Empty;
			return false;
		}

		public void LogErrors(System.CodeDom.Compiler.CompilerErrorCollection errors) {
			Errors = errors;
		}

		public AppDomain ProvideTemplatingAppDomain(string content) {
			AppDomain = AppDomain.CreateDomain(this.GetType().Name);
			return AppDomain;
		}

		public string ResolveAssemblyReference(string assemblyReference) {
			if(File.Exists(assemblyReference))
				return assemblyReference;

			try {
				var assembly = Assembly.Load(assemblyReference);
				if (assembly != null)
					return assembly.Location;
			}
			catch { }

			return string.Empty;
		}

		public Type ResolveDirectiveProcessor(string processorName) {
			throw new Exception(string.Format("Directive processor {0} not found.", processorName));
		}

		public string ResolveParameterValue(string directiveId, string processorName, string parameterName) {
			return string.Empty;
		}

		public string ResolvePath(string path) {
			if(File.Exists(path))
				return path;

			return string.Empty;
		}

		public void SetFileExtension(string extension) {
		}

		public void SetOutputEncoding(Encoding encoding, bool fromOutputDirective) {
		}

		public IList<string> StandardAssemblyReferences {
			get {
				return new string[] {
					typeof(System.Guid).Assembly.Location,
					typeof(System.Data.DataSet).Assembly.Location,
					typeof(System.CodeDom.Compiler.CodeCompiler).Assembly.Location,
					typeof(CoNatural.Data.ICommand).Assembly.Location,
					typeof(TemplateHost).Assembly.Location
				};
			}
		}

		public IList<string> StandardImports {
			get {
				return new string[] {
					"System",
					"System.Data",
					"CoNatural.Data",
					"CoNatural.Data.VisualStudio.AddIn.Tools",
				};
			}
		}

		public string TemplateFile {
			get { return string.Empty; }
		}

		#endregion

		#region IDisposable Members

		public void Dispose() {
			if (AppDomain != null) {
				AppDomain.Unload(AppDomain);
				AppDomain = null;
			}
		}

		#endregion
	}
}
